<template>
  <div> CsTool </div>
  <el-upload
    ref="upload"
    class="upload-demo"
    action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
    :on-exceed="handleExceed"
    :on-change="handleChange"
    :auto-upload="false"
    :on-success="handleSuccess"
    :on-error="handleError"
    :limit="2"
    multiple
  >
    <template #trigger>
      <el-button 
        type="primary" 
        :disabled="st.select_file_button_disable"
      >
        select file 
      </el-button>
    </template>

    <el-button 
      class="ml-3" 
      type="success" 
      :disabled="st.upload_button_disable"
      @click="submitUpload" 
    >
      upload to server
    </el-button>

    <el-divider />

    <template #tip>
      <div class="el-upload__tip text-red">
        请上传两个文件，名称类似: 
      </div>
      <div class="el-upload__tip text-red">
        [2024] wk[n] 1711.csv
      </div>
      <div class="el-upload__tip text-red">
        [2024] wk[n] 1713.csv
      </div>
    </template>
  </el-upload>

  <el-divider />

  <div 
    v-show="st.result_table_is_show"
    class="list-group" 
  >
    <a 
      href="#" 
      class="list-group-item list-group-item-action active" 
      aria-current="true"
    >
      处理结果文件为: 
    </a>

    <a 
      :href="first_result.url" 
      class="list-group-item"
    >
      {{ first_result.url }}--{{ first_result.update_timestamp }}
    </a>
    <a 
      :href="first_result.url" 
      class="list-group-item"
    >
      {{ first_result.url }}--{{ first_result.update_timestamp }}
    </a>
    <a 
      :href="first_result.url" 
      class="list-group-item"
    >
      {{ first_result.url }}--{{ first_result.update_timestamp }}
    </a>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'
import type { UploadInstance, UploadProps, UploadRawFile } from 'element-plus'
import type { UploadFile, UploadFiles } from 'element-plus'
import { genFileId } from 'element-plus'


class UploadStatus {
  private _select_file_button_enable: ref<boolean>;
  private _upload_button_enable: ref<boolean>;
  private _result_tab_is_show: ref<boolean>;


  public constructor(st_select_file, st_upload, st_result_tab) {
    this._select_file_button_enable = ref<boolean>(st_select_file);
    this._upload_button_enable = ref<boolean>(st_upload);
    this._result_tab_is_show = ref<boolean>(st_result_tab);

    this._upload_file_map = ref<Map>(new Map());
  }

  public get select_file_button_disable(): ref<boolean> {
    return !this._select_file_button_enable
  }

  public get upload_button_disable(): ref<boolean>{
    return !this._upload_button_enable;
  }
  public get result_table_is_show(): ref<boolean> {
    return this._result_tab_is_show;
  }




  public enable_select_file_button(){
    this._select_file_button_enable = true
  }
  public disable_select_file_button(){
    this._select_file_button_enable = false
  }

  public enable_upload_button(){
    this._upload_button_enable = true
  }
  public disable_upload_button(){
    this._upload_button_enable = false
  }

  public result_table_is_hide(): boolean {
    return this._result_tab_is_show == false  
  }
  public show_result_table(){
    this._result_tab_is_show = true
  }
  public hide_result_table(){
    this._result_tab_is_show = false
  }

}


class Result {
  private _url: ref<string>;
  private _update_ts: ref<string>;

  constructor(url: string = ''){
    this._url = ref<string>(url);
    this._update_ts = new Date().toLocaleTimeString();
  }

  public get url(): ref<string>{
    return this._url;
  }
  public set url(value: string): void {
    this._url.value = value
  }

  public get update_timestamp(): ref<string>{
    return this._update_ts;
  }

  public refresh(): void {
    this._update_ts = new Date().toLocaleTimeString();
  }

}

const st = reactive<UploadStatus>(new UploadStatus(true, false, false));
const upload = ref<UploadInstance>()
const first_result = reactive<Result>(new Result())

let upload_file_map : Map = new Map();



// will be called when add-ok, upload-success, upload-failed 
const handleChange: UploadProps['onChange'] = (uploadFile: UploadFile, 
  uploadFiles: UploadFiles) => {
  console.log("on-change, file count:" + uploadFiles.length.toString());

  if(uploadFiles.length === 2){
    const is_upload_file_ready = (f) => f.status === 'ready';
    if(uploadFiles.every(is_upload_file_ready)){
      st.enable_upload_button();
    }
  }
}

const handleExceed: UploadProps['onExceed'] = (files) => {
    upload.value!.clearFiles();
    console.log("on-exceed:" + files.length.toString())

    if(files.length >= 0){
        const file = files[0] as UploadRawFile
        file.uid = genFileId()
        upload.value!.handleStart(file)

        st.hide_result_table();
    }
}

const handleSuccess: UploadProps['onSuccess'] = (response: unknown, uploadFile: UploadFile, 
    uploadFiles: UploadFiles) => {

    console.log("upload success file name:" + uploadFile.name)
    console.log("upload on-success, waiting file count:" + uploadFiles.length.toString())

    upload_file_map.set(uploadFile.name,'success');

    if(uploadFiles.length === 0){ // this is last upload file

      const is_upload_file_commited = (st) => (st === 'fail' || st === 'success');
      if(upload_file_map.size == 2 
        && upload_file_map.values().every(is_upload_file_commited)){


        //TODO: get the result of two-file; and save the result, and show result table
        first_result.url = "https://www.baidu.com"
        first_result.refresh()

        st.show_result_table()
      }
    }
}
const handleError: UploadProps['onError'] = (error: Error, uploadFile: UploadFile, 
    uploadFiles: UploadFiles) => {
    console.log("upload error file name:" + uploadFile.name)
    console.log("upload on-error, waiting file count:" + uploadFiles.length.toString())

    upload_file_map.set(uploadFile.name, 'fail')

    if(uploadFiles.length === 0){
      const is_upload_file_commited = (st) => (st === 'fail' || st === 'success');
      if(upload_file_map.size == 2 
        && upload_file_map.values().every(is_upload_file_commited)){

        st.show_result_table()
      }
    }
}

const submitUpload = () => {
  console.log('submit the upload');
  st.disable_select_file_button()

  st.disable_upload_button()

  upload.value!.submit()


  st.enable_select_file_button()
}



</script>
